<script lang="tsx">
import { defineComponent, ref, computed, type PropType, type ExtractPropTypes } from 'vue'
import { ElButton } from 'element-plus'
import { IgnoreProps, SchedulePromise, downloadBlob } from './utils'
import { Plus } from '@element-plus/icons-vue'
import axios from 'axios'
export const oDownloadSelfProps = {
  formData: {
    type: Object,
    required: true
  },
  prop: {
    type: String,
    required: true
  },
  perm: {
    type: String,
    default: 'true'
  },
  visiable: {
    type: Boolean,
    default: true
  },
  ...IgnoreProps
}
export const oDownloadProps = {
  ...oDownloadSelfProps
}
export type oDownloadPropsType = ExtractPropTypes<typeof oDownloadProps>
const oDownload = defineComponent({
  name: 'one-Download',
  props: oDownloadProps,
  // inheritAttrs: false,
  components: { Plus, ElButton },
  setup(props: oDownloadPropsType, context) {
    async function concurrencyDownload(path: string, size: number, chunkSize: number) {
      const chunkNum = Math.ceil(size / chunkSize)
      const downloadTask = []
      for (let i = 0; i < chunkNum; i++) {
        const rangeStart = chunkSize * i
        const rangeEnd = chunkSize * (i + 1) - 1
        downloadTask.push([rangeStart, rangeEnd])
      }
      // const arrayBuffers = await Promise.all(
      //   downloadTask.map((task) => {
      //     return task.then((res) => res.data)
      //   })
      // )
      const arrayBuffers: ArrayBuffer[] = []
      const scheduleTasks = downloadTask.map((task, index) => {
        return (resolve: Function) =>
          axios
            .get(path, {
              headers: {
                Range: `bytes=${task[0]}-${task[1]}`
              },
              responseType: 'arraybuffer'
            })
            .then((res: any) => {
              arrayBuffers[index] = res.data
              resolve()
            })
      })
      await new Promise((resolve) => {
        new SchedulePromise(resolve).push(scheduleTasks)
      })
      return mergeArrayBuffer(arrayBuffers)
    }

    function mergeArrayBuffer(arrays: ArrayBuffer[]) {
      let totalLength = 0
      for (let arr of arrays) {
        totalLength += arr.byteLength
      }
      let res = new Uint8Array(totalLength)
      let offset = 0
      for (let arr of arrays) {
        let unit8Array = new Uint8Array(arr)
        res.set(unit8Array, offset)
        offset += arr.byteLength
      }
      return res.buffer
    }

    async function onDownload() {
      // 获取文件长度，因为分片不能超出长度
      // 发送请求，header头Range定义分片区间
      // 合并收到的 ArrayBuffer但是因为不能操纵，需要用子类DataView，用Unit8Array接收
      // 合并从blob文件格式
      const { data: length } = await axios.get('http://localhost:1112/length')
      const res = await concurrencyDownload('http://localhost:1112', length, 3000)
      const blob = new Blob([res])
      // 下载
      downloadBlob(blob, '1.png')
    }

    return () => (
      <ElButton size="small" type="primary" onClick={onDownload}>
        下载文件
      </ElButton>
    )
  }
})
export default oDownload
</script>
<style lang="scss" scoped>
.el-upload__tip {
  line-height: initial;
}
</style>
